package com.zkh.myframe.aspect;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import com.zkh.myutils.proxy.MethodHandler;
import com.zkh.myutils.proxy.ProxyMethod;

/**
 * 切面代理
 * @author zkh
 */
public final class AspectProxy implements MethodHandler{
	
	//方法pattern
	private List<String> methodPatternList;
	//切面集合
	private List<AspectSuper> aspectList;
	//切面长度
	private int len;
	
	/**
	 * 构造方法
	 * @param aspectList 切面集合（一个方法可存在多个切面）
	 */
	public AspectProxy(List<String> methodPatternList, List<AspectSuper> aspectList){
		this.methodPatternList = methodPatternList;
		this.aspectList = aspectList;
		this.len = methodPatternList.size();
	}

	/**
	 * 执行代理方法
	 */
	public Object invoke(Object proxy, ProxyMethod proxyMethod) throws Throwable {
		//方法名
		String methodName = proxyMethod.getSuperName();
		//有效切面
		List<AspectSuper> avls = new ArrayList<>();
		/** 处理前置操作 **/
		for(int i=0;i<len;i++) {
			//判断是否拦截
			if(methodName.matches(methodPatternList.get(i))) {
				//执行前置操作
				Object rtnVal = aspectList.get(i).before(proxyMethod.getArgs());
				//布尔值
				if(rtnVal instanceof Boolean) {
					//为false，停止执行
					if(!((Boolean) rtnVal).booleanValue()) {
						return null;
					}
				}//其它值，直接返回
				else{
					return rtnVal;
				}
				//保存有效切面
				avls.add(0, aspectList.get(i));
			}
		}

		/** 执行被代理方法 **/
		//结果值
		Object res = null;
		//是否发生异常
		boolean exp = false;
		try {
			//执行被代理方法
			res = proxyMethod.invoke(proxy, proxyMethod.getArgs());
		}catch(InvocationTargetException e) {
			//标记异常
			exp = true;
			//执行异常捕获
			for(AspectSuper avl: avls) {
				res = avl.catchException(proxyMethod.getArgs(), e.getTargetException(), res);
			}
		}
		
		/** 后置操作 **/
		//没有发生异常，执行后置方法
		if(!exp) {
			for(AspectSuper avl: avls) {
				res = avl.after(proxyMethod.getArgs(), res);
			}
		}
		//返回结果
		return res;
	}

}
